import {
	KanBanActionType,
	IKanBanStore,
	IKanBanAbility,
	IKanBanController,
	IKanBanControllerParams,
	IParam,
	IKanBanModel,
	ICtrlActionResult,
} from '@/core/interface';
import { ControlVOBase } from '@/core/modules';
import KanBanService from '@/core/modules/ctrl-service/kanban-service';
import { deepCopy } from '@/core/utils';
import { MDCtrlController } from './md-ctrl-controller';

/**
 * 看板部件控制器
 *
 * @export
 * @class KanBanController
 * @extends {(MDCtrlController<T | KanBanActionType, IKanBanStore, IKanBanAbility>)}
 * @implements {IKanBanController}
 * @template T
 */
export class KanBanController
	extends MDCtrlController<KanBanActionType, IKanBanStore, IKanBanAbility>
	implements IKanBanController<IKanBanStore, IKanBanAbility>
{
	/**
	 * 多数据部件模型
	 *
	 * @protected
	 * @type {IMDCtrlModel}
	 * @memberof KanBanController
	 */
	declare model: IKanBanModel;

	/**
	 * 部件服务
	 *
	 * @type {FormService<ControlVOBase>}
	 * @memberof KanBanController
	 */
	declare ctrlService: KanBanService<ControlVOBase>;

	/**
	 * 行激活模式 (0: 无激活、1: 单击激活、2: 双击激活)
	 *
	 * @protected
	 * @type {(0 | 1 | 2)}
	 * @memberof KanBanController
	 */
	protected rowActiveMode!: 0 | 1 | 2;

	/**
	 * Creates an instance of KanBanController.
	 * @param {IKanBanControllerParams<KanBanActionType, IKanBanAbility>} params
	 * @memberof KanBanController
	 */
	public constructor(
		params: IKanBanControllerParams<KanBanActionType, IKanBanAbility>
	) {
		super(params);
		this.rowActiveMode = params.rowActiveMode;
		this.ctrlInit(params);
	}

	/**
	 * 处理部件初始化
	 *
	 * @protected
	 * @param {IKanBanControllerParams<KanBanActionType, IKanBanAbility>} params
	 * @memberof KanBanController
	 */
	protected processCtrlInit(
		params: IKanBanControllerParams<KanBanActionType, IKanBanAbility>
	) {
		super.processCtrlInit(params);
		this.name = 'kanban';
	}

	/**
	 * 处理加载行为数据
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof KanBanController
	 */
	protected handleLoadDataChange(data: IParam[]): void {
		this.store.data = data;
		this.handleGroup();
	}

	/**
	 * 看板项单击
	 *
	 * @param {IParam} item
	 * @param {MouseEvent} event
	 * @memberof KanBanController
	 */
	itemClick(item: IParam, event: MouseEvent) {
		const selections = this.store.selections;
		if (this.singleSelect) {
			selections.length = 0;
			selections.push(item);
		} else {
			const index = selections.findIndex(
				(select: IParam) => select.srfkey === item.srfkey
			);
			//	未选中
			if (index === -1) {
				this.store.selections.push(item);
			} else {
				this.store.selections.splice(index, 1);
			}
		}
		this.emit('selectionChange', this.getData());
		if (this.rowActiveMode === 1) {
			this.emit('dataActive', [item]);
		}
	}

	/**
	 * 看板项双击
	 *
	 * @param {IParam} item
	 * @param {MouseEvent} event
	 * @memberof KanBanController
	 */
	itemDbClick(item: IParam, event: MouseEvent) {
		const selections = this.store.selections;
		if (this.singleSelect) {
			selections.length = 0;
			selections.push(item);
		} else {
			const index = selections.findIndex(
				(select: IParam) => select.srfkey === item.srfkey
			);
			//	未选中
			if (index === -1) {
				this.store.selections.push(item);
			} else {
				this.store.selections.splice(index, 1);
			}
		}
		this.emit('selectionChange', this.getData());
		if (this.rowActiveMode === 2) {
			this.emit('dataActive', [item]);
		}
	}

	/**
	 * 选中数据
	 *
	 * @param {IParam[]} selections
	 * @memberof KanBanController
	 */
	selectionChange(selections: IParam[]) {
		this.store.selections = selections;
		this.emit('selectionChange', this.getData());
	}

	/**
	 * 拖拽变化
	 *
	 * @param {*} evt 拖住对象
	 * @param {*} name 分组名
	 * @memberof KanBanController
	 */
	public async dragChange(evt: any, data: any) {
		if (evt?.added?.element) {
			const item: any = evt.added.element;
			const updateView = '';
			if (updateView) {
				// todo updateView
			} else {
				const { groupField, entityCodeName } = this.model;
				if (groupField) {
					item[groupField] = data.value;
				}
				this.save(item);
				// 重新分组
			}
		}
	}

	/**
	 * 多数据部件数据更新
	 *
	 * @param {*} opts
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof KanBanController
	 */
	public async save(opts: IParam): Promise<ICtrlActionResult> {
		const { entityCodeName } = this.model;
		const { viewParams, context, data } = this.store;
		const { updateAction } = this.actions;
		if (!updateAction) {
			console.warn(App.ts("widget.kanban.notconfig.notconfigsaveaction","未配置保存行为"));
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const arg: any = deepCopy(viewParams);
		const tempContext: any = deepCopy(context);
		if (entityCodeName) {
			Object.assign(tempContext, {
				[entityCodeName.toLowerCase() as string]: opts.srfkey,
			});
		}
		try {
			this.beforeAsyncAction('save', tempContext, arg);
			const response: any = await this.ctrlService.save(
				updateAction,
				tempContext,
				{
					...opts.$DO,
					viewParams: arg,
				}
			);
			if (!response.success) {
				this.afterAsyncAction('save', response);
				return {
					ok: false,
					data: this.getData(),
					rowData: response,
				};
			}
			this.emit('save', response.data);
			this.afterAsyncAction('save', response);
			return {
				ok: true,
				data: this.getData(),
				rowData: response,
			};
		} catch (error: any) {
			this.afterAsyncAction('save', error);
			return {
				ok: false,
				data: this.getData(),
				rowData: error,
			};
		}
	}

	/**
	 * 多数据部件数据删除
	 *
	 * @param {*} datas
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof KanBanController
	 */
	async remove(datas: IParam = {}): Promise<ICtrlActionResult> {
		const { removeAction } = this.actions;
		if (!removeAction) {
			App.getNotificationHelper().warning(App.ts("widget.common.warn","警告"),App.ts("widget.kanban.notconfig.notconfigdeleteaction","未配置删除行为"));
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const deleteItems: IParam[] = [];
		//	已选中数据
		datas.forEach((record: IParam) => {
			if (record.srfuf === '0') {
				const index = this.store.data.findIndex(
					(i: IParam) => i.srfkey === record.srfkey
				);
				if (index !== -1) {
					this.store.data.splice(index, 1);
				}
			} else {
				deleteItems.push(record);
			}
		});
		if (deleteItems.length === 0) {
			return { ok: true, data: this.getData(), rowData: { status: 200 } };
		}
		let dataInfo = '';
		deleteItems.forEach((item: IParam, index: number) => {
			if (index < 5) {
				if (dataInfo !== '') {
					dataInfo += '、';
				}
				dataInfo += item.srfmajortext ? item.srfmajortext : '';
			}
		});
		if (!dataInfo) {
			dataInfo = `${App.ts("widget.kanban.check","选中")}${deleteItems.length}${App.ts("widget.kanban.piece","条数据")}`;
		} else {
			if (deleteItems.length < 5) {
				dataInfo += ` ${App.ts("widget.kanban.total","共")}${deleteItems.length}${App.ts("widget.kanban.piece","条数据")}`;
			} else {
				dataInfo += `...${deleteItems.length}${App.ts("widget.kanban.piece","条数据")}`;
			}
		}
		//	去除null和undefined
		dataInfo = dataInfo.replace(/[null]/g, '').replace(/[undefined]/g, '');
		const removeData = () => {
			const keys: string[] = [];
			deleteItems.forEach((item: IParam) => keys.push(item.srfkey));
			if (keys.length === 0) {
				return;
			}
			const { context, viewParams } = this.store;
			let _removeAction = removeAction;
			if (Object.is(removeAction, 'RemoveTemp') && keys.length > 1) {
				_removeAction = 'RemoveBatchTemp';
			}
			const tempContext: any = deepCopy(context);
			const _keys: string[] | string = keys.length > 1 ? keys : keys[0];
			const { entityCodeName } = this.model;
			const arg = { [entityCodeName.toLowerCase()]: _keys };
			let promises: Promise<any> | null = null;
			if (keys && keys.length > 1) {
				const promiseArr: any = [];
				(_keys as string[]).forEach((ele: any) => {
					Object.assign(tempContext, { [entityCodeName.toLowerCase()]: ele });
					Object.assign(arg, { viewParams: deepCopy(viewParams) });
					Object.assign(arg, { [entityCodeName.toLowerCase()]: ele });
					promiseArr.push(
						this.ctrlService.delete(_removeAction, tempContext, arg)
					);
				});
				promises = Promise.all(promiseArr);
			} else {
				Object.assign(tempContext, { [entityCodeName.toLowerCase()]: _keys });
				Object.assign(arg, { viewParams: deepCopy(viewParams) });
				promises = this.ctrlService.delete(_removeAction, tempContext, arg);
			}
			this.beforeAsyncAction('remove', tempContext, arg);
			if (promises) {
				promises
					.then(async (response: any) => {
						this.afterAsyncAction('remove', response, { afterNotification: `, ${response.info}`});
						//删除items中已删除的项
						this.store.totalRecord -= deleteItems.length;
						this.emit('remove', deleteItems);
						this.store.selections = [];
					})
					.catch(async (error: any) => {
						this.afterAsyncAction('remove', error);
					});
			}
		};
		App.getDialogHelper().confirm(
			App.ts("widget.common.warn","警告"),
			`${App.ts("widget.common.confirmtodelete","确认要删除")}${dataInfo}, ${App.ts("widget.common.delnotberecoverable","删除操作将不可恢复")}?`,
			() => {
				removeData();
			}
		);
		return { ok: true, data: this.getData(), rowData: { status: 200 } };
	}

	/**
	 * 获取能力
	 *
	 * @template A
	 * @return {*}  {A}
	 * @memberof GridController
	 */
	getAbility(): IKanBanAbility {
		return {
			...super.getAbility(),
			save: this.save.bind(this),
			remove: this.remove.bind(this),
		};
	}
}
